#include "QAbstractTreeModel.h"

#include <QAbstractTreeNode.h>
#include <QStandardTreeNode.h>

QAbstractTreeModel::QAbstractTreeModel(const QStringList& headers, QObject* parent)
    : QAbstractItemModel(parent)
{
	QList<QVariant> rootData;
	foreach(QString header, headers)
		rootData << header;
    rootNode = new QStandardTreeNode(rootData);
    rootNode->setModel(this);
    connect(rootNode, SIGNAL(layoutAboutToBeChanged()), this, SIGNAL(layoutAboutToBeChanged()));
    connect(rootNode, SIGNAL(layoutChanged()), this, SIGNAL(layoutChanged()));
}

QAbstractTreeModel::~QAbstractTreeModel()
{
	if(rootNode) delete rootNode;
}

QAbstractTreeNode* QAbstractTreeModel::getNode(const QModelIndex& index) const
{
	if (index.isValid()) {
         QAbstractTreeNode *node = static_cast<QAbstractTreeNode*>(index.internalPointer());
		 if(node)
			return node;
	 }
	 return rootNode;
}

QVariant QAbstractTreeModel::data(const QModelIndex &index, int role) const
{
    //QAbstractTreeNode *node = static_cast<QAbstractTreeNode*>(index.internalPointer());
    //if(!node) node = rootNode;
    QAbstractTreeNode* node = getNode(index);
	if(node)
        return node->data(index.column(), role);
	return QVariant();
}

QVariant QAbstractTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Horizontal)
         return rootNode->data(section, role);
	 return QVariant();
}

QModelIndex QAbstractTreeModel::index(int row, int column, const QModelIndex &parent) const
{
	if (parent.isValid() && parent.column() != 0)
        return QModelIndex();

    QAbstractTreeNode *parentNode = getNode(parent);
    QAbstractTreeNode *childNode = parentNode->childAt(row);
    if (childNode)
        return createIndex(row, column, childNode);
    return QModelIndex();
}

QModelIndex QAbstractTreeModel::parent(const QModelIndex &index) const
{
	if (!index.isValid())
		 return QModelIndex();

    QAbstractTreeNode *childNode = getNode(index);
    QAbstractTreeNode* parentNode = childNode->parent();
	 if (parentNode == rootNode)
		 return QModelIndex();
	 return createIndex(parentNode->row(), 0, parentNode);
}

int QAbstractTreeModel::rowCount(const QModelIndex &parent) const
{
     QAbstractTreeNode *parentNode = getNode(parent);
	 return parentNode->childCount();
}

int QAbstractTreeModel::columnCount(const QModelIndex &parent) const
{
    QAbstractTreeNode* parentNode = getNode(parent);
	return parentNode->columnCount();
}

Qt::ItemFlags QAbstractTreeModel::flags(const QModelIndex &index) const
{
    QAbstractTreeNode* node = getNode(index);
    return node->flags(index.column());
}

bool QAbstractTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    QAbstractTreeNode* node = getNode(index);
	if(!node) return false;
    bool result = node->setData(value, index.column(), role);
	if(result)
		emit dataChanged(index, index);
	return result;
}

bool QAbstractTreeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
     if (orientation != Qt::Horizontal)
		 return false;
     bool result = rootNode->setData(value, section, role);
	 if (result)
		 emit headerDataChanged(orientation, section, section);
	 return result;
}

bool QAbstractTreeModel::insertColumns(int position, int columns, const QModelIndex &index)
{
    QAbstractTreeNode* node = getNode(index);
    if(node)
       return node->insertColumns(position, columns);
    return false;
}

bool QAbstractTreeModel::removeColumns(int position, int columns, const QModelIndex &index)
{
    QAbstractTreeNode* node = getNode(index);
    if(node)
        return node->removeColumns(position, columns);
    return false;
}

bool QAbstractTreeModel::insertRows(int position, int rows, const QModelIndex &parent)
{
    Q_UNUSED(position)
    Q_UNUSED(rows)
    Q_UNUSED(parent)
    return false;
}

bool QAbstractTreeModel::removeRows(int position, int rows, const QModelIndex &parent)
{
    Q_UNUSED(position)
    Q_UNUSED(rows)
    Q_UNUSED(parent)
    return false;
}

void QAbstractTreeModel::refreshData()
{
    // refresh all
    emit this->dataChanged(QModelIndex(), QModelIndex());
}
